package com.test.controller;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.util.StringUtils;

/**
 * Excel工具类:可同时适应.xls和.xlsx
 * @author yezhang
 *
 */
public class ExcelUtils {

    private Workbook wb;
    private Sheet sheet;
    private Row row;
    
    /**
     * 读取Excel表格表头的内容
     * @return String 表头内容的数组
     */
    @SuppressWarnings("deprecation")
	public String[] readExcelTitle(InputStream is) throws Exception{
    	wb = WorkbookFactory.create(is);
        sheet = wb.getSheetAt(0);
        row = sheet.getRow(0);
        // 标题总列数
        int colNum = row.getPhysicalNumberOfCells();
        String[] title = new String[colNum];
        for (int i = 0; i < colNum; i++) {
            title[i] = getCellFormatValue(row.getCell((short) i));
        }
        return title;
    }

    /**
     * 读取Excel数据内容
     * @return Map 包含单元格数据内容的Map对象
     */
    @SuppressWarnings("deprecation")
	public List<Map<Integer, String>> readExcelContent(InputStream is) throws Exception{
    	wb = WorkbookFactory.create(is);
        sheet = wb.getSheetAt(0);
        // 得到总行数
        int rowNum = sheet.getLastRowNum();
        row = sheet.getRow(0);
        int colNum = row.getPhysicalNumberOfCells();
        // 正文内容应该从第二行开始,第一行为表头的标题
        List<Map<Integer, String>> contentList = new ArrayList<Map<Integer,String>>();
        for (int i = 1; i <= rowNum; i++) {
        	Map<Integer, String> content = new HashMap<Integer, String>();
            row = sheet.getRow(i);
            if (row == null){
                return contentList;
            }
            int j = 0;
            while (j < colNum) {
            	String str = getCellFormatValue(row.getCell((short) j)).trim();
                content.put(j, str);
                j++;
            }
            contentList.add(content);
        }
        return contentList;
    }
    
    public String exportExcel(String[] excelTitle, List<Map<Integer, String>> excelContent, String xlsPath, String fileName) throws Exception{
    	FileOutputStream fos = null;
    	Workbook wb = new SXSSFWorkbook();
    	if (StringUtils.isEmpty(xlsPath)) {
			xlsPath = "/home/temp";
		}
    	if (StringUtils.isEmpty(fileName)) {
    		fileName = String.valueOf(System.currentTimeMillis()) + ".xls";
		}
		File xlsPathDirectory = new File(xlsPath);
		if (!xlsPathDirectory.isDirectory()) {
			xlsPathDirectory.mkdirs();
		}
		File templateFile = new File(xlsPath + fileName);
		if (!templateFile.exists()){
			templateFile.createNewFile();
		}
		
//		Font font = wb.createFont();
//		font.setBoldweight(Font.BOLDWEIGHT_BOLD);
//		CellStyle cellStyle = wb.createCellStyle();
//		cellStyle.setFont(font);
		Sheet sheet = wb.createSheet("sheet1");
		
		int rowNum = 0;
		Row row = sheet.createRow(rowNum);
		setExcelTitle(excelTitle, row);
		for (Map<Integer, String> content : excelContent) {
			rowNum ++;
			row = sheet.createRow(rowNum);
			setExcelContent(content, row);
		}
		fos = new FileOutputStream(templateFile, true);
		wb.write(fos);
		fos.flush();
		fos.close();
		return templateFile.getPath();
    }
    
    private void setExcelContent(Map<Integer, String> content, Row row){
    	for (int index = 0; index < content.size(); index ++) {
    		Cell cell = null;
    		cell = row.createCell(index);
    		cell.setCellValue(content.get(index));
		}
    }
    
    private void setExcelTitle(String[] excelTitle, Row row){
    	for (int index = 0; index < excelTitle.length; index ++) {
    		Cell cell = null;
    		cell = row.createCell(index);
    		cell.setCellValue(excelTitle[index]);
		}
    }

    /**
     * 获取单元格数据内容为字符串类型的数据
     * 
     * @param cell Excel单元格
     * @return String 单元格数据内容
     */
    private String getStringCellValue(HSSFCell cell) {
        String strCell = "";
        if (cell != null) {
	        switch (cell.getCellType()) {
	        case HSSFCell.CELL_TYPE_STRING:
	            strCell = cell.getStringCellValue();
	            break;
	        case HSSFCell.CELL_TYPE_NUMERIC:
	            strCell = String.valueOf(cell.getNumericCellValue());
	            break;
	        case HSSFCell.CELL_TYPE_BOOLEAN:
	            strCell = String.valueOf(cell.getBooleanCellValue());
	            break;
	        case HSSFCell.CELL_TYPE_BLANK:
	            strCell = "";
	            break;
	        default:
	            strCell = "";
	            break;
	        }
	        if (strCell.equals("") || strCell == null) {
	        	strCell = "";
	        }
        }else{
        	strCell = "";
        }
        return strCell;
    }

    /**
     * 获取单元格数据内容为日期类型的数据
     * 
     * @param cell
     *            Excel单元格
     * @return String 单元格数据内容
     */
    private String getDateCellValue(HSSFCell cell) {
        String result = "";
        try {
            int cellType = cell.getCellType();
            if (cellType == HSSFCell.CELL_TYPE_NUMERIC) {
                Date date = cell.getDateCellValue();
                result = (date.getYear() + 1900) + "-" + (date.getMonth() + 1)
                        + "-" + date.getDate();
            } else if (cellType == HSSFCell.CELL_TYPE_STRING) {
                String date = getStringCellValue(cell);
                result = date.replaceAll("[年月]", "-").replace("日", "").trim();
            } else if (cellType == HSSFCell.CELL_TYPE_BLANK) {
                result = "";
            }
        } catch (Exception e) {
            System.out.println("日期格式不正确!");
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 根据HSSFCell类型设置数据
     * @param cell
     * @return
     */
    private String getCellFormatValue(Cell cell) {
        String cellvalue = "";
        if (cell != null) {
            // 判断当前Cell的Type
            switch (cell.getCellType()) {
            // 如果当前Cell的Type为NUMERIC
            case HSSFCell.CELL_TYPE_NUMERIC:
            	
            case HSSFCell.CELL_TYPE_FORMULA: {
                // 判断当前的cell是否为Date
                if (HSSFDateUtil.isCellDateFormatted(cell)) {
                    // 如果是Date类型则，转化为Data格式
                    
                    //方法1：这样子的data格式是带时分秒的：2011-10-12 0:00:00
                    //cellvalue = cell.getDateCellValue().toLocaleString();
                    
                    //方法2：这样子的data格式是不带带时分秒的：2011-10-12
                    Date date = cell.getDateCellValue();
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                    cellvalue = sdf.format(date).trim();
//                    cellvalue = cell.getRichStringCellValue().toString();
                }
                // 如果是纯数字
                else {
                    // 取得当前Cell的数值
                    cellvalue = String.valueOf(cell.getNumericCellValue()).trim();
                }
                break;
            }
            // 如果当前Cell的Type为STRIN
            case HSSFCell.CELL_TYPE_STRING:
                // 取得当前的Cell字符串
                cellvalue = cell.getRichStringCellValue().getString().trim();
                break;
            // 默认的Cell值
            default:
                cellvalue = "";
            }
        } else {
            cellvalue = "";
        }
        return cellvalue;

    }

    public void exportExcel(String title, JSONArray jsonArray, List<Map<String, String>> eventRecordMapList,
                            OutputStream out) {
        // 创建一个excel工作簿
        HSSFWorkbook workbook = new HSSFWorkbook();
        HSSFSheet sheet = workbook.createSheet(title);
        // excel列默认宽度
        sheet.setDefaultColumnWidth(20);

        // 第一行标题样式（白字蓝底）
        HSSFCellStyle titleStyle = workbook.createCellStyle();
        HSSFPalette palette = workbook.getCustomPalette();
        palette.setColorAtIndex((short) 63, (byte) (50), (byte) (126), (byte) (179));
        titleStyle.setFillForegroundColor((short) 63);
        titleStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
        titleStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
        titleStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
        titleStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
        titleStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
        titleStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
        HSSFFont font = workbook.createFont();
        font.setColor(HSSFColor.WHITE.index);
        font.setFontHeightInPoints((short) 12);
        font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
        titleStyle.setFont(font);
        titleStyle.setWrapText(false);

        // 内容行样式 （白底黑字）
        HSSFCellStyle contentStyle = workbook.createCellStyle();
        contentStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
        contentStyle.setFillForegroundColor(HSSFColor.WHITE.index);
        contentStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
        contentStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
        contentStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);
        contentStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
        contentStyle.setAlignment(HSSFCellStyle.ALIGN_LEFT);
        contentStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
        HSSFFont font2 = workbook.createFont();
        font2.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
        contentStyle.setFont(font2);
        contentStyle.setWrapText(true);

        HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
        HSSFComment comment = patriarch.createComment(new HSSFClientAnchor(0, 0, 0, 0, (short) 4, 2, (short) 6, 5));
        comment.setString(new HSSFRichTextString("数据列表"));
        comment.setAuthor("csh");

        // 填充标题,就是第一行啦
        HSSFRow row = sheet.createRow(0);
        row.setHeight((short) 500);
        for (short i = 0; i < jsonArray.length(); i++) {
            HSSFCell cell = row.createCell(i);
            cell.setCellStyle(titleStyle);
            JSONObject jsonObject = jsonArray.getJSONObject(i);
            HSSFRichTextString text = new HSSFRichTextString(jsonObject.getString("headerName"));
            cell.setCellValue(text);
        }

        // 填充内容行，就是除第一行外的所有行，从第二行开始
        for (int i = 0; i < eventRecordMapList.size(); i++) {
            row = sheet.createRow(i + 1);
            row.setHeight((short) 350);
            Map<String, String> eventRecordMap = eventRecordMapList.get(i);

            for (int j = 0; j < jsonArray.length(); j++) {
                JSONObject jsonObject = jsonArray.getJSONObject(j);
                HSSFCell cell = row.createCell(j);
                cell.setCellStyle(contentStyle);
                try {
                    String textValue = eventRecordMap.get(jsonObject.getString("header"));

                    if (textValue != null) {
                        Pattern p = Pattern.compile("^//d+(//.//d+)?$"); // 匹配是否是数值类型
                        Matcher matcher = p.matcher(textValue);
                        if (matcher.matches()) {
                            cell.setCellValue(Double.parseDouble(textValue));
                        } else {
                            HSSFRichTextString richString = new HSSFRichTextString(textValue);
                            HSSFFont font3 = workbook.createFont();
                            font3.setColor(HSSFColor.BLACK.index);
                            richString.applyFont(font3);
                            cell.setCellValue(richString);
                        }
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                } finally {

                }
            }

        }
        try {
            workbook.write(out);// 将excel工作簿写入到输出流中
//             workbook.close();//关闭

        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}
